//go:build !trial
// +build !trial

package rule

import (
	"github.com/actiontech/sqle/sqle/driver/mysql/plocale"
	driverV2 "github.com/actiontech/sqle/sqle/driver/v2"
	"github.com/actiontech/sqle/sqle/pkg/params"
	"github.com/pingcap/parser/ast"
)

var sourceRuleHandlers = []*SourceHandler{
	{
		Rule: SourceRule{
			Name:       DMLNotAllowInsertAutoincrement,
			Desc:       plocale.DMLNotAllowInsertAutoincrementDesc,
			Annotation: plocale.DMLNotAllowInsertAutoincrementAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLNotAllowInsertAutoincrementMessage,
		AllowOffline: false,
		Func:         notAllowInsertAutoincrement,
	},
	{
		Rule: SourceRule{
			Name:       ConfigDMLRollbackMaxRows,
			Desc:       plocale.ConfigDMLRollbackMaxRowsDesc,
			Annotation: plocale.ConfigDMLRollbackMaxRowsAnnotation,
			//Value:    "1000",
			Level:    driverV2.RuleLevelNotice,
			Category: plocale.RuleTypeGlobalConfig,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  plocale.ConfigDMLRollbackMaxRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},
	{
		Rule: SourceRule{
			Name:       ConfigDDLOSCMinSize,
			Desc:       plocale.ConfigDDLOSCMinSizeDesc,
			Annotation: plocale.ConfigDDLOSCMinSizeAnnotation,
			//Value:    "16",
			Level:    driverV2.RuleLevelNormal,
			Category: plocale.RuleTypeGlobalConfig,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.ConfigDDLOSCMinSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTableSize,
			Desc:       plocale.DDLCheckTableSizeDesc,
			Annotation: plocale.DDLCheckTableSizeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DDLCheckTableSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                 plocale.DDLCheckTableSizeMessage,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkDDLTableSize,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexTooMany,
			Desc:       plocale.DDLCheckIndexTooManyDesc,
			Annotation: plocale.DDLCheckIndexTooManyAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeIndexingConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2",
					Desc:  plocale.DDLCheckIndexTooManyParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckIndexTooManyMessage,
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       ConfigDMLExplainPreCheckEnable,
			Desc:       plocale.ConfigDMLExplainPreCheckEnableDesc,
			Annotation: plocale.ConfigDMLExplainPreCheckEnableAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeGlobalConfig,
		},
		Func: nil,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckRedundantIndex,
			Desc:       plocale.DDLCheckRedundantIndexDesc,
			Annotation: plocale.DDLCheckRedundantIndexAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexOptimization,
		},
		Message:                         plocale.DDLCheckRedundantIndexMessage,
		AllowOffline:                    true,
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckTableSize,
			Desc:       plocale.DMLCheckTableSizeDesc,
			Annotation: plocale.DMLCheckTableSizeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DMLCheckTableSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckTableSizeMessage,
		Func:    checkDMLTableSize,
	},
	{
		Rule: SourceRule{
			Name:       ConfigOptimizeIndexEnabled,
			Desc:       plocale.ConfigOptimizeIndexEnabledDesc,
			Annotation: plocale.ConfigOptimizeIndexEnabledAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeIndexOptimization,
			Params: []*SourceParam{
				{
					Key:   DefaultMultiParamsFirstKeyName,
					Value: "2.00",
					Desc:  plocale.ConfigOptimizeIndexEnabledParams1,
					Type:  params.ParamTypeFloat64,
				},
				{
					Key:   DefaultMultiParamsSecondKeyName,
					Value: "3",
					Desc:  plocale.ConfigOptimizeIndexEnabledParams2,
					Type:  params.ParamTypeInt,
				},
			},
		},
	},

	{
		Rule: SourceRule{
			Name:       ConfigSQLIsExecuted,
			Desc:       plocale.ConfigSQLIsExecutedDesc,
			Annotation: plocale.ConfigSQLIsExecutedAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeGlobalConfig,
		},
	},

	{
		Rule: SourceRule{
			Name:       ConfigDDLGhostMinSize,
			Desc:       plocale.ConfigDDLGhostMinSizeDesc,
			Annotation: plocale.ConfigDDLGhostMinSizeAnnotation,
			//Value:    "16",
			Level:    driverV2.RuleLevelNormal,
			Category: plocale.RuleTypeGlobalConfig,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.ConfigDDLGhostMinSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Func: nil,
	},

	// rule
	{
		Rule: SourceRule{
			Name:       DDLCheckPKWithoutIfNotExists,
			Desc:       plocale.DDLCheckPKWithoutIfNotExistsDesc,
			Annotation: plocale.DDLCheckPKWithoutIfNotExistsAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckPKWithoutIfNotExistsMessage,
		AllowOffline: true,
		Func:         checkIfNotExist,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckObjectNameLength,
			Desc:       plocale.DDLCheckObjectNameLengthDesc,
			Annotation: plocale.DDLCheckObjectNameLengthAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
			//Value:    "64",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "64",
					Desc:  plocale.DDLCheckObjectNameLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DDLCheckObjectNameLengthMessage,
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckObjectNameIsUpperAndLowerLetterMixed,
			Desc:       plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedDesc,
			Annotation: plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedAnnotation,
			Category:   plocale.RuleTypeNamingConvention,
			Level:      driverV2.RuleLevelNotice,
		},
		Message:      plocale.DDLCheckObjectNameIsUpperAndLowerLetterMixedMessage,
		Func:         checkIsObjectNameUpperAndLowerLetterMixed,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckPKNotExist,
			Desc:       plocale.DDLCheckPKNotExistDesc,
			Annotation: plocale.DDLCheckPKNotExistAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                         plocale.DDLCheckPKNotExistMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckPKWithoutAutoIncrement,
			Desc:       plocale.DDLCheckPKWithoutAutoIncrementDesc,
			Annotation: plocale.DDLCheckPKWithoutAutoIncrementAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                         plocale.DDLCheckPKWithoutAutoIncrementMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckPKWithoutBigintUnsigned,
			Desc:       plocale.DDLCheckPKWithoutBigintUnsignedDesc,
			Annotation: plocale.DDLCheckPKWithoutBigintUnsignedAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                         plocale.DDLCheckPKWithoutBigintUnsignedMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckJoinFieldType,
			Desc:       plocale.DMLCheckJoinFieldTypeDesc,
			Annotation: plocale.DMLCheckJoinFieldTypeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckJoinFieldTypeMessage,
		AllowOffline: false,
		Func:         checkJoinFieldType,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckHasJoinCondition,
			Desc:       plocale.DMLCheckHasJoinConditionDesc,
			Annotation: plocale.DMLCheckHasJoinConditionAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckHasJoinConditionMessage,
		AllowOffline: true,
		Func:         checkHasJoinCondition,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnCharLength,
			Desc:       plocale.DDLCheckColumnCharLengthDesc,
			Annotation: plocale.DDLCheckColumnCharLengthAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnCharLengthMessage,
		AllowOffline: true,
		Func:         checkStringType,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckFieldNotNUllMustContainDefaultValue,
			Desc:       plocale.DDLCheckFieldNotNUllMustContainDefaultValueDesc,
			Annotation: plocale.DDLCheckFieldNotNUllMustContainDefaultValueAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckFieldNotNUllMustContainDefaultValueMessage,
		AllowOffline: true,
		Func:         checkFieldNotNUllMustContainDefaultValue,
	},
	{
		Rule: SourceRule{
			Name:       DDLDisableFK,
			Desc:       plocale.DDLDisableFKDesc,
			Annotation: plocale.DDLDisableFKAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:      plocale.DDLDisableFKMessage,
		AllowOffline: true,
		Func:         checkForeignKey,
	},
	{
		Rule: SourceRule{
			Name:       DDLDisableAlterFieldUseFirstAndAfter,
			Desc:       plocale.DDLDisableAlterFieldUseFirstAndAfterDesc,
			Annotation: plocale.DDLDisableAlterFieldUseFirstAndAfterAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLDisableAlterFieldUseFirstAndAfterMessage,
		AllowOffline: true,
		Func:         disableAlterUseFirstAndAfter,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCreateTimeColumn,
			Desc:       plocale.DDLCheckCreateTimeColumnDesc,
			Annotation: plocale.DDLCheckCreateTimeColumnAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "CREATE_TIME",
					Desc:  plocale.DDLCheckCreateTimeColumnParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckCreateTimeColumnMessage,
		AllowOffline: true,
		Func:         checkFieldCreateTime,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexCount,
			Desc:       plocale.DDLCheckIndexCountDesc,
			Annotation: plocale.DDLCheckIndexCountAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "5",
			Category: plocale.RuleTypeIndexingConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "5",
					Desc:  plocale.DDLCheckIndexCountParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckIndexCountMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckUpdateTimeColumn,
			Desc:       plocale.DDLCheckUpdateTimeColumnDesc,
			Annotation: plocale.DDLCheckUpdateTimeColumnAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "UPDATE_TIME",
					Desc:  plocale.DDLCheckUpdateTimeColumnParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckUpdateTimeColumnMessage,
		AllowOffline: true,
		Func:         checkFieldUpdateTime,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCompositeIndexMax,
			Desc:       plocale.DDLCheckCompositeIndexMaxDesc,
			Annotation: plocale.DDLCheckCompositeIndexMaxAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "3",
			Category: plocale.RuleTypeIndexingConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DDLCheckCompositeIndexMaxParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:                         plocale.DDLCheckCompositeIndexMaxMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            checkIndex,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexNotNullConstraint,
			Desc:       plocale.DDLCheckIndexNotNullConstraintDesc,
			Annotation: plocale.DDLCheckIndexNotNullConstraintAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:              plocale.DDLCheckIndexNotNullConstraintMessage,
		AllowOffline:         true,
		NotAllowOfflineStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                 checkIndexNotNullConstraint,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckObjectNameUsingKeyword,
			Desc:       plocale.DDLCheckObjectNameUsingKeywordDesc,
			Annotation: plocale.DDLCheckObjectNameUsingKeywordAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
		},
		Message:      plocale.DDLCheckObjectNameUsingKeywordMessage,
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckObjectNameUseCN,
			Desc:       plocale.DDLCheckObjectNameUseCNDesc,
			Annotation: plocale.DDLCheckObjectNameUseCNAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
		},
		Message:      plocale.DDLCheckObjectNameUseCNMessage,
		AllowOffline: true,
		Func:         checkNewObjectName,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTableDBEngine,
			Desc:       plocale.DDLCheckTableDBEngineDesc,
			Annotation: plocale.DDLCheckTableDBEngineAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
			//Value:    "Innodb",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "Innodb",
					Desc:  plocale.DDLCheckTableDBEngineParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckTableDBEngineMessage,
		AllowOffline: false,
		Func:         checkEngine,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTableCharacterSet,
			Desc:       plocale.DDLCheckTableCharacterSetDesc,
			Annotation: plocale.DDLCheckTableCharacterSetAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
			//Value:    "utf8mb4",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4",
					Desc:  plocale.DDLCheckTableCharacterSetParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckTableCharacterSetMessage,
		AllowOffline: false,
		Func:         checkCharacterSet,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexedColumnWithBlob,
			Desc:       plocale.DDLCheckIndexedColumnWithBlobDesc,
			Annotation: plocale.DDLCheckIndexedColumnWithBlobAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                         plocale.DDLCheckIndexedColumnWithBlobMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}, &ast.CreateIndexStmt{}},
		Func:                            disableAddIndexForColumnsTypeBlob,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereIsInvalid,
			Desc:       plocale.DMLCheckWhereIsInvalidDesc,
			Annotation: plocale.DMLCheckWhereIsInvalidAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWhereIsInvalidMessage,
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckAlterTableNeedMerge,
			Desc:       plocale.DDLCheckAlterTableNeedMergeDesc,
			Annotation: plocale.DDLCheckAlterTableNeedMergeAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:                 plocale.DDLCheckAlterTableNeedMergeMessage,
		AllowOffline:            false,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkMergeAlterTable,
	},
	{
		Rule: SourceRule{
			Name:       DMLDisableSelectAllColumn,
			Desc:       plocale.DMLDisableSelectAllColumnDesc,
			Annotation: plocale.DMLDisableSelectAllColumnAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLDisableSelectAllColumnMessage,
		AllowOffline: true,
		Func:         checkSelectAll,
	},
	{
		Rule: SourceRule{
			Name:       DDLDisableDropStatement,
			Desc:       plocale.DDLDisableDropStatementDesc,
			Annotation: plocale.DDLDisableDropStatementAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLDisableDropStatementMessage,
		AllowOffline: true,
		Func:         disableDropStmt,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTableWithoutComment,
			Desc:       plocale.DDLCheckTableWithoutCommentDesc,
			Annotation: plocale.DDLCheckTableWithoutCommentAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckTableWithoutCommentMessage,
		AllowOffline: true,
		Func:         checkTableWithoutComment,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnWithoutComment,
			Desc:       plocale.DDLCheckColumnWithoutCommentDesc,
			Annotation: plocale.DDLCheckColumnWithoutCommentAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnWithoutCommentMessage,
		AllowOffline: true,
		Func:         checkColumnWithoutComment,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexPrefix,
			Desc:       plocale.DDLCheckIndexPrefixDesc,
			Annotation: plocale.DDLCheckIndexPrefixAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
			//Value:    "idx_",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "idx_",
					Desc:  plocale.DDLCheckIndexPrefixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckIndexPrefixMessage,
		AllowOffline: true,
		Func:         checkIndexPrefix,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckUniqueIndexPrefix,
			Desc:       plocale.DDLCheckUniqueIndexPrefixDesc,
			Annotation: plocale.DDLCheckUniqueIndexPrefixAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
			//Value:    "uniq_",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "uniq_",
					Desc:  plocale.DDLCheckUniqueIndexPrefixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckUniqueIndexPrefixMessage,
		AllowOffline: true,
		Func:         checkUniqIndexPrefix,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckUniqueIndex,
			Desc:       plocale.DDLCheckUniqueIndexDesc,
			Annotation: plocale.DDLCheckUniqueIndexAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeNamingConvention,
		},
		Message:      plocale.DDLCheckUniqueIndexMessage,
		AllowOffline: true,
		Func:         checkUniqIndex,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnWithoutDefault,
			Desc:       plocale.DDLCheckColumnWithoutDefaultDesc,
			Annotation: plocale.DDLCheckColumnWithoutDefaultAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnWithoutDefaultMessage,
		AllowOffline: true,
		Func:         checkColumnWithoutDefault,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnTimestampWithoutDefault,
			Desc:       plocale.DDLCheckColumnTimestampWithoutDefaultDesc,
			Annotation: plocale.DDLCheckColumnTimestampWithoutDefaultAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnTimestampWithoutDefaultMessage,
		AllowOffline: true,
		Func:         checkColumnTimestampWithoutDefault,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnBlobWithNotNull,
			Desc:       plocale.DDLCheckColumnBlobWithNotNullDesc,
			Annotation: plocale.DDLCheckColumnBlobWithNotNullAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnBlobWithNotNullMessage,
		AllowOffline: true,
		Func:         checkColumnBlobNotNull,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnBlobDefaultIsNotNull,
			Desc:       plocale.DDLCheckColumnBlobDefaultIsNotNullDesc,
			Annotation: plocale.DDLCheckColumnBlobDefaultIsNotNullAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnBlobDefaultIsNotNullMessage,
		AllowOffline: true,
		Func:         checkColumnBlobDefaultNull,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckAutoIncrementFieldNum,
			Desc:       plocale.DDLCheckAutoIncrementFieldNumDesc,
			Annotation: plocale.DDLCheckAutoIncrementFieldNumAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DDLCheckAutoIncrementFieldNumMessage,
		Func:         checkAutoIncrementFieldNum,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckAllIndexNotNullConstraint,
			Desc:       plocale.DDLCheckAllIndexNotNullConstraintDesc,
			Annotation: plocale.DDLCheckAllIndexNotNullConstraintAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DDLCheckAllIndexNotNullConstraintMessage,
		Func:         checkAllIndexNotNullConstraint,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWithLimit,
			Desc:       plocale.DMLCheckWithLimitDesc,
			Annotation: plocale.DMLCheckWithLimitAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWithLimitMessage,
		AllowOffline: true,
		Func:         checkDMLWithLimit,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSelectLimit,
			Desc:       plocale.DMLCheckSelectLimitDesc,
			Annotation: plocale.DMLCheckSelectLimitAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  plocale.DMLCheckSelectLimitParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckSelectLimitMessage,
		AllowOffline: true,
		Func:         checkSelectLimit,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWithOrderBy,
			Desc:       plocale.DMLCheckWithOrderByDesc,
			Annotation: plocale.DMLCheckWithOrderByAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWithOrderByMessage,
		AllowOffline: true,
		Func:         checkDMLWithOrderBy,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSelectWithOrderBy,
			Desc:       plocale.DMLCheckSelectWithOrderByDesc,
			Annotation: plocale.DMLCheckSelectWithOrderByAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckSelectWithOrderByMessage,
		AllowOffline: true,
		Func:         checkSelectWithOrderBy,
	},
	{
		// TODO: 修改level以适配默认模板
		Rule: SourceRule{
			Name:       DMLCheckInsertColumnsExist,
			Desc:       plocale.DMLCheckInsertColumnsExistDesc,
			Annotation: plocale.DMLCheckInsertColumnsExistAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckInsertColumnsExistMessage,
		AllowOffline: true,
		Func:         checkDMLWithInsertColumnExist,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckBatchInsertListsMax,
			Desc:       plocale.DMLCheckBatchInsertListsMaxDesc,
			Annotation: plocale.DMLCheckBatchInsertListsMaxAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "5000",
			Category: plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.DMLCheckBatchInsertListsMaxParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckBatchInsertListsMaxMessage,
		AllowOffline: true,
		Func:         checkDMLWithBatchInsertMaxLimits,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckInQueryNumber,
			Desc:       plocale.DMLCheckInQueryNumberDesc,
			Annotation: plocale.DMLCheckInQueryNumberAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "50",
					Desc:  plocale.DMLCheckInQueryNumberParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckInQueryNumberMessage,
		AllowOffline: true,
		Func:         checkInQueryLimit,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckPKProhibitAutoIncrement,
			Desc:       plocale.DDLCheckPKProhibitAutoIncrementDesc,
			Annotation: plocale.DDLCheckPKProhibitAutoIncrementAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                         plocale.DDLCheckPKProhibitAutoIncrementMessage,
		AllowOffline:                    true,
		NotAllowOfflineStmts:            []ast.Node{&ast.AlterTableStmt{}},
		NotSupportExecutedSQLAuditStmts: []ast.Node{&ast.AlterTableStmt{}},
		Func:                            checkPrimaryKey,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereExistFunc,
			Desc:       plocale.DMLCheckWhereExistFuncDesc,
			Annotation: plocale.DMLCheckWhereExistFuncAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWhereExistFuncMessage,
		AllowOffline: false,
		Func:         checkWhereExistFunc,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereExistNot,
			Desc:       plocale.DMLCheckWhereExistNotDesc,
			Annotation: plocale.DMLCheckWhereExistNotAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWhereExistNotMessage,
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:       DMLWhereExistNull,
			Desc:       plocale.DMLWhereExistNullDesc,
			Annotation: plocale.DMLWhereExistNullAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLWhereExistNullMessage,
		Func:         checkWhereExistNull,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereExistImplicitConversion,
			Desc:       plocale.DMLCheckWhereExistImplicitConversionDesc,
			Annotation: plocale.DMLCheckWhereExistImplicitConversionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckWhereExistImplicitConversionMessage,
		Func:    checkWhereColumnImplicitConversion,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckLimitMustExist,
			Desc:       plocale.DMLCheckLimitMustExistDesc,
			Annotation: plocale.DMLCheckLimitMustExistAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckLimitMustExistMessage,
		Func:         checkDMLLimitExist,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckWhereExistScalarSubquery,
			Desc:       plocale.DMLCheckWhereExistScalarSubqueryDesc,
			Annotation: plocale.DMLCheckWhereExistScalarSubqueryAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckWhereExistScalarSubqueryMessage,
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexesExistBeforeCreateConstraints,
			Desc:       plocale.DDLCheckIndexesExistBeforeCreateConstraintsDesc,
			Annotation: plocale.DDLCheckIndexesExistBeforeCreateConstraintsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeIndexingConvention,
		},
		Message:                 plocale.DDLCheckIndexesExistBeforeCreateConstraintsMessage,
		OnlyAuditNotExecutedSQL: true,
		Func:                    checkIndexesExistBeforeCreatConstraints,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSelectForUpdate,
			Desc:       plocale.DMLCheckSelectForUpdateDesc,
			Annotation: plocale.DMLCheckSelectForUpdateAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckSelectForUpdateMessage,
		Func:         checkDMLSelectForUpdate,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckDatabaseCollation,
			Desc:       plocale.DDLCheckDatabaseCollationDesc,
			Annotation: plocale.DDLCheckDatabaseCollationAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "utf8mb4_0900_ai_ci",
			Category: plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "utf8mb4_0900_ai_ci",
					Desc:  plocale.DDLCheckDatabaseCollationParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message: plocale.DDLCheckDatabaseCollationMessage,
		Func:    checkCollationDatabase,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckDecimalTypeColumn,
			Desc:       plocale.DDLCheckDecimalTypeColumnDesc,
			Annotation: plocale.DDLCheckDecimalTypeColumnAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckDecimalTypeColumnMessage,
		Func:         checkDecimalTypeColumn,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckBigintInsteadOfDecimal,
			Desc:       plocale.DDLCheckBigintInsteadOfDecimalDesc,
			Annotation: plocale.DDLCheckBigintInsteadOfDecimalAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckBigintInsteadOfDecimalMessage,
		Func:         checkBigintInsteadOfDecimal,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSubQueryNestNum,
			Desc:       plocale.DMLCheckSubQueryNestNumDesc,
			Annotation: plocale.DMLCheckSubQueryNestNumAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DMLCheckSubQueryNestNumParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckSubQueryNestNumMessage,
		Func:         checkSubQueryNestNum,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckNeedlessFunc,
			Desc:       plocale.DMLCheckNeedlessFuncDesc,
			Annotation: plocale.DMLCheckNeedlessFuncAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "sha(),sqrt(),md5()",
			Category: plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "sha(),sqrt(),md5()",
					Desc:  plocale.DMLCheckNeedlessFuncParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DMLCheckNeedlessFuncMessage,
		Func:         checkNeedlessFunc,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckDatabaseSuffix,
			Desc:       plocale.DDLCheckDatabaseSuffixDesc,
			Annotation: plocale.DDLCheckDatabaseSuffixAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeNamingConvention,
			//Value:    "_DB",
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "_DB",
					Desc:  plocale.DDLCheckDatabaseSuffixParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		Message:      plocale.DDLCheckDatabaseSuffixMessage,
		Func:         checkDatabaseSuffix,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckPKName,
			Desc:       plocale.DDLCheckPKNameDesc,
			Annotation: plocale.DDLCheckPKNameAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeNamingConvention,
		},
		Message:      plocale.DDLCheckPKNameMessage,
		Func:         checkPKIndexName,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTransactionIsolationLevel,
			Desc:       plocale.DDLCheckTransactionIsolationLevelDesc,
			Annotation: plocale.DDLCheckTransactionIsolationLevelAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckTransactionIsolationLevelMessage,
		Func:         checkTransactionIsolationLevel,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckFuzzySearch,
			Desc:       plocale.DMLCheckFuzzySearchDesc,
			Annotation: plocale.DMLCheckFuzzySearchAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckFuzzySearchMessage,
		AllowOffline: true,
		Func:         checkSelectWhere,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckTablePartition,
			Desc:       plocale.DDLCheckTablePartitionDesc,
			Annotation: plocale.DDLCheckTablePartitionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckTablePartitionMessage,
		AllowOffline: true,
		Func:         checkTablePartition,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckNumberOfJoinTables,
			Desc:       plocale.DMLCheckNumberOfJoinTablesDesc,
			Annotation: plocale.DMLCheckNumberOfJoinTablesAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "3",
			Category: plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "3",
					Desc:  plocale.DMLCheckNumberOfJoinTablesParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckNumberOfJoinTablesMessage,
		AllowOffline: true,
		Func:         checkNumberOfJoinTables,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckIfAfterUnionDistinct,
			Desc:       plocale.DMLCheckIfAfterUnionDistinctDesc,
			Annotation: plocale.DMLCheckIfAfterUnionDistinctAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckIfAfterUnionDistinctMessage,
		AllowOffline: true,
		Func:         checkIsAfterUnionDistinct,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIsExistLimitOffset,
			Desc:       plocale.DDLCheckIsExistLimitOffsetDesc,
			Annotation: plocale.DDLCheckIsExistLimitOffsetAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DDLCheckIsExistLimitOffsetMessage,
		AllowOffline: true,
		Func:         checkIsExistLimitOffset,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckIndexOption,
			Desc:       plocale.DDLCheckIndexOptionDesc,
			Annotation: plocale.DDLCheckIndexOptionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			//Value:    "0.7",
			Category: plocale.RuleTypeIndexOptimization,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "70",
					Desc:  plocale.DDLCheckIndexOptionParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DDLCheckIndexOptionMessage,
		AllowOffline: false,
		Func:         checkIndexOption,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnEnumNotice,
			Desc:       plocale.DDLCheckColumnEnumNoticeDesc,
			Annotation: plocale.DDLCheckColumnEnumNoticeAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnEnumNoticeMessage,
		AllowOffline: true,
		Func:         checkColumnEnumNotice,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnSetNotice,
			Desc:       plocale.DDLCheckColumnSetNoticeDesc,
			Annotation: plocale.DDLCheckColumnSetNoticeAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnSetNoticeMessage,
		AllowOffline: true,
		Func:         checkColumnSetNotice,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnBlobNotice,
			Desc:       plocale.DDLCheckColumnBlobNoticeDesc,
			Annotation: plocale.DDLCheckColumnBlobNoticeAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLCheckColumnBlobNoticeMessage,
		AllowOffline: true,
		Func:         checkColumnBlobNotice,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainAccessTypeAll,
			Desc:       plocale.DMLCheckExplainAccessTypeAllDesc,
			Annotation: plocale.DMLCheckExplainAccessTypeAllAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10000",
					Desc:  plocale.DMLCheckExplainAccessTypeAllParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckExplainAccessTypeAllMessage,
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainExtraUsingFilesort,
			Desc:       plocale.DMLCheckExplainExtraUsingFilesortDesc,
			Annotation: plocale.DMLCheckExplainExtraUsingFilesortAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckExplainExtraUsingFilesortMessage,
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainExtraUsingTemporary,
			Desc:       plocale.DMLCheckExplainExtraUsingTemporaryDesc,
			Annotation: plocale.DMLCheckExplainExtraUsingTemporaryAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckExplainExtraUsingTemporaryMessage,
		AllowOffline: false,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCreateView,
			Desc:       plocale.DDLCheckCreateViewDesc,
			Annotation: plocale.DDLCheckCreateViewAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckCreateViewMessage,
		AllowOffline: true,
		Func:         checkCreateView,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCreateTrigger,
			Desc:       plocale.DDLCheckCreateTriggerDesc,
			Annotation: plocale.DDLCheckCreateTriggerAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckCreateTriggerMessage,
		AllowOffline: true,
		Func:         checkCreateTrigger,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCreateFunction,
			Desc:       plocale.DDLCheckCreateFunctionDesc,
			Annotation: plocale.DDLCheckCreateFunctionAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckCreateFunctionMessage,
		AllowOffline: true,
		Func:         checkCreateFunction,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCreateProcedure,
			Desc:       plocale.DDLCheckCreateProcedureDesc,
			Annotation: plocale.DDLCheckCreateProcedureAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		Message:      plocale.DDLCheckCreateProcedureMessage,
		AllowOffline: true,
		Func:         checkCreateProcedure,
	},
	{
		Rule: SourceRule{
			Name:       DDLDisableTypeTimestamp,
			Desc:       plocale.DDLDisableTypeTimestampDesc,
			Annotation: plocale.DDLDisableTypeTimestampAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message:      plocale.DDLDisableTypeTimestampMessage,
		AllowOffline: true,
		Func:         disableUseTypeTimestampField,
	},
	{
		Rule: SourceRule{ //select a as id, id , b as user  from mysql.user;
			Name:       DMLCheckAlias,
			Desc:       plocale.DMLCheckAliasDesc,
			Annotation: plocale.DMLCheckAliasAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckAliasMessage,
		Func:    checkAlias,
	},
	{
		Rule: SourceRule{ //ALTER TABLE test CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
			Name:       DDLHintUpdateTableCharsetWillNotUpdateFieldCharset,
			Desc:       plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetDesc,
			Annotation: plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintUpdateTableCharsetWillNotUpdateFieldCharsetMessage,
		Func:    hintUpdateTableCharsetWillNotUpdateFieldCharset,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP COLUMN col;
			Name:       DDLHintDropColumn,
			Desc:       plocale.DDLHintDropColumnDesc,
			Annotation: plocale.DDLHintDropColumnAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropColumnMessage,
		Func:    hintDropColumn,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP PRIMARY KEY;
			Name:       DDLHintDropPrimaryKey,
			Desc:       plocale.DDLHintDropPrimaryKeyDesc,
			Annotation: plocale.DDLHintDropPrimaryKeyAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropPrimaryKeyMessage,
		Func:    hintDropPrimaryKey,
	},
	{
		Rule: SourceRule{ //ALTER TABLE tbl DROP FOREIGN KEY a;
			Name:       DDLHintDropForeignKey,
			Desc:       plocale.DDLHintDropForeignKeyDesc,
			Annotation: plocale.DDLHintDropForeignKeyAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLHintDropForeignKeyMessage,
		Func:    hintDropForeignKey,
	},
	{
		Rule: SourceRule{ //select * from user where id like "a";
			Name:       DMLNotRecommendNotWildcardLike,
			Desc:       plocale.DMLNotRecommendNotWildcardLikeDesc,
			Annotation: plocale.DMLNotRecommendNotWildcardLikeAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendNotWildcardLikeMessage,
		Func:    notRecommendNotWildcardLike,
	},
	{
		Rule: SourceRule{ //SELECT * FROM tb WHERE col IN (NULL);
			Name:       DMLHintInNullOnlyFalse,
			Desc:       plocale.DMLHintInNullOnlyFalseDesc,
			Annotation: plocale.DMLHintInNullOnlyFalseAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintInNullOnlyFalseMessage,
		Func:    hintInNullOnlyFalse,
	},
	{
		Rule: SourceRule{ //select * from user where id in (a);
			Name:       DMLNotRecommendIn,
			Desc:       plocale.DMLNotRecommendInDesc,
			Annotation: plocale.DMLNotRecommendInAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendInMessage,
		Func:    notRecommendIn,
	},
	{
		Rule: SourceRule{ //select * from user where id = ' 1';
			Name:       DMLCheckSpacesAroundTheString,
			Desc:       plocale.DMLCheckSpacesAroundTheStringDesc,
			Annotation: plocale.DMLCheckSpacesAroundTheStringAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSpacesAroundTheStringMessage,
		Func:    checkSpacesAroundTheString,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tb (a varchar(10) default '“');
			Name:       DDLCheckFullWidthQuotationMarks,
			Desc:       plocale.DDLCheckFullWidthQuotationMarksDesc,
			Annotation: plocale.DDLCheckFullWidthQuotationMarksAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckFullWidthQuotationMarksMessage,
		Func:    checkFullWidthQuotationMarks,
	},
	{
		Rule: SourceRule{ //select name from tbl where id < 1000 order by rand(1)
			Name:       DMLNotRecommendOrderByRand,
			Desc:       plocale.DMLNotRecommendOrderByRandDesc,
			Annotation: plocale.DMLNotRecommendOrderByRandAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendOrderByRandMessage,
		Func:    notRecommendOrderByRand,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl group by 1
			Name:       DMLNotRecommendGroupByConstant,
			Desc:       plocale.DMLNotRecommendGroupByConstantDesc,
			Annotation: plocale.DMLNotRecommendGroupByConstantAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendGroupByConstantMessage,
		Func:    notRecommendGroupByConstant,
	},
	{
		Rule: SourceRule{ //select c1,c2,c3 from t1 where c1='foo' order by c2 desc, c3 asc
			Name:       DMLCheckSortDirection,
			Desc:       plocale.DMLCheckSortDirectionDesc,
			Annotation: plocale.DMLCheckSortDirectionAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSortDirectionMessage,
		Func:    checkSortDirection,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl group by 1
			Name:       DMLHintGroupByRequiresConditions,
			Desc:       plocale.DMLHintGroupByRequiresConditionsDesc,
			Annotation: plocale.DMLHintGroupByRequiresConditionsAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintGroupByRequiresConditionsMessage,
		Func:    hintGroupByRequiresConditions,
	},
	{
		Rule: SourceRule{ //select description from film where title ='ACADEMY DINOSAUR' order by length-language_id;
			Name:       DMLNotRecommendGroupByExpression,
			Desc:       plocale.DMLNotRecommendGroupByExpressionDesc,
			Annotation: plocale.DMLNotRecommendGroupByExpressionAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendGroupByExpressionMessage,
		Func:    notRecommendGroupByExpression,
	},
	{
		Rule: SourceRule{ //select description from film where title ='ACADEMY DINOSAUR' order by length-language_id;
			Name:       DMLCheckSQLLength,
			Desc:       plocale.DMLCheckSQLLengthDesc,
			Annotation: plocale.DMLCheckSQLLengthAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DMLCheckSQLLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DMLCheckSQLLengthMessage,
		Func:    checkSQLLength,
	},
	{
		Rule: SourceRule{ //SELECT s.c_id,count(s.c_id) FROM s where c = test GROUP BY s.c_id HAVING s.c_id <> '1660' AND s.c_id <> '2' order by s.c_id
			Name:       DMLNotRecommendHaving,
			Desc:       plocale.DMLNotRecommendHavingDesc,
			Annotation: plocale.DMLNotRecommendHavingAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendHavingMessage,
		Func:    notRecommendHaving,
	},
	{
		Rule: SourceRule{ //delete from tbl
			Name:       DMLHintUseTruncateInsteadOfDelete,
			Desc:       plocale.DMLHintUseTruncateInsteadOfDeleteDesc,
			Annotation: plocale.DMLHintUseTruncateInsteadOfDeleteAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintUseTruncateInsteadOfDeleteMessage,
		Func:    hintUseTruncateInsteadOfDelete,
	},
	{
		Rule: SourceRule{ //update mysql.func set name ="hello";
			Name:       DMLNotRecommendUpdatePK,
			Desc:       plocale.DMLNotRecommendUpdatePKDesc,
			Annotation: plocale.DMLNotRecommendUpdatePKAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendUpdatePKMessage,
		Func:    notRecommendUpdatePK,
	},
	{
		Rule: SourceRule{ //create table t(c1 int,c2 int,c3 int,c4 int,c5 int,c6 int);
			Name:       DDLCheckColumnQuantity,
			Desc:       plocale.DDLCheckColumnQuantityDesc,
			Annotation: plocale.DDLCheckColumnQuantityAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "40",
					Desc:  plocale.DDLCheckColumnQuantityParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DDLCheckColumnQuantityMessage,
		Func:         checkColumnQuantity,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{ //CREATE TABLE `tb2` ( `id` int(11) DEFAULT NULL, `col` char(10) CHARACTER SET utf8 DEFAULT NULL)
			Name:       DDLRecommendTableColumnCharsetSame,
			Desc:       plocale.DDLRecommendTableColumnCharsetSameDesc,
			Annotation: plocale.DDLRecommendTableColumnCharsetSameAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLRecommendTableColumnCharsetSameMessage,
		Func:    recommendTableColumnCharsetSame,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tab (a INT(1));
			Name:       DDLCheckColumnTypeInteger,
			Desc:       plocale.DDLCheckColumnTypeIntegerDesc,
			Annotation: plocale.DDLCheckColumnTypeIntegerAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckColumnTypeIntegerMessage,
		Func:    checkColumnTypeInteger,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tab (a varchar(3500));
			Name:       DDLCheckVarcharSize,
			Desc:       plocale.DDLCheckVarcharSizeDesc,
			Annotation: plocale.DDLCheckVarcharSizeAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1024",
					Desc:  plocale.DDLCheckVarcharSizeParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckVarcharSizeMessage,
		Func:    checkVarcharSize,
	},
	{
		Rule: SourceRule{ //select id from t where substring(name,1,3)='abc'
			Name:       DMLNotRecommendFuncInWhere,
			Desc:       plocale.DMLNotRecommendFuncInWhereDesc,
			Annotation: plocale.DMLNotRecommendFuncInWhereAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendFuncInWhereMessage,
		Func:    notRecommendFuncInWhere,
	},
	{
		Rule: SourceRule{ //SELECT SYSDATE();
			Name:       DMLNotRecommendSysdate,
			Desc:       plocale.DMLNotRecommendSysdateDesc,
			Annotation: plocale.DMLNotRecommendSysdateAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendSysdateMessage,
		Func:    notRecommendSysdate,
	},
	{
		Rule: SourceRule{ //SELECT SUM(COL) FROM tbl;
			Name:       DMLHintSumFuncTips,
			Desc:       plocale.DMLHintSumFuncTipsDesc,
			Annotation: plocale.DMLHintSumFuncTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintSumFuncTipsMessage,
		Func:    hintSumFuncTips,
	},
	{
		Rule: SourceRule{
			Name:       DMLHintCountFuncWithCol,
			Desc:       plocale.DMLHintCountFuncWithColDesc,
			Annotation: plocale.DMLHintCountFuncWithColAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLHintCountFuncWithColMessage,
		Func:         hintCountFuncWithCol,
		AllowOffline: true,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnQuantityInPK,
			Desc:       plocale.DDLCheckColumnQuantityInPKDesc,
			Annotation: plocale.DDLCheckColumnQuantityInPKAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2",
					Desc:  plocale.DDLCheckColumnQuantityInPKParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckColumnQuantityInPKMessage,
		Func:    checkColumnQuantityInPK,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl where name=xx limit 10
			Name:       DMLHintLimitMustBeCombinedWithOrderBy,
			Desc:       plocale.DMLHintLimitMustBeCombinedWithOrderByDesc,
			Annotation: plocale.DMLHintLimitMustBeCombinedWithOrderByAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintLimitMustBeCombinedWithOrderByMessage,
		Func:    hintLimitMustBeCombinedWithOrderBy,
	},
	{
		Rule: SourceRule{ //TRUNCATE TABLE tbl_name
			Name:       DMLHintTruncateTips,
			Desc:       plocale.DMLHintTruncateTipsDesc,
			Annotation: plocale.DMLHintTruncateTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintTruncateTipsMessage,
		Func:    hintTruncateTips,
	},
	{
		Rule: SourceRule{ //delete from t where col = 'condition'
			Name:       DMLHintDeleteTips,
			Desc:       plocale.DMLHintDeleteTipsDesc,
			Annotation: plocale.DMLHintDeleteTipsAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLHintDeleteTipsMessage,
		Func:    hintDeleteTips,
	},
	{
		Rule: SourceRule{ //SELECT BENCHMARK(10, RAND())
			Name:       DMLCheckSQLInjectionFunc,
			Desc:       plocale.DMLCheckSQLInjectionFuncDesc,
			Annotation: plocale.DMLCheckSQLInjectionFuncAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSQLInjectionFuncMessage,
		Func:    checkSQLInjectionFunc,
	},
	{
		Rule: SourceRule{ //select col1,col2 from tbl where type!=0
			Name:       DMLCheckNotEqualSymbol,
			Desc:       plocale.DMLCheckNotEqualSymbolDesc,
			Annotation: plocale.DMLCheckNotEqualSymbolAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckNotEqualSymbolMessage,
		Func:    checkNotEqualSymbol,
	},
	{
		Rule: SourceRule{ //select col1,col2,col3 from table1 where col2 in(select col from table2)
			Name:       DMLNotRecommendSubquery,
			Desc:       plocale.DMLNotRecommendSubqueryDesc,
			Annotation: plocale.DMLNotRecommendSubqueryAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLNotRecommendSubqueryMessage,
		Func:    notRecommendSubquery,
	},
	{
		Rule: SourceRule{ //SELECT * FROM staff WHERE name IN (SELECT NAME FROM customer ORDER BY name LIMIT 1)
			Name:       DMLCheckSubqueryLimit,
			Desc:       plocale.DMLCheckSubqueryLimitDesc,
			Annotation: plocale.DMLCheckSubqueryLimitAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message: plocale.DMLCheckSubqueryLimitMessage,
		Func:    checkSubqueryLimit,
	},
	{
		Rule: SourceRule{ //CREATE TABLE tbl (a int) AUTO_INCREMENT = 10;
			Name:       DDLCheckAutoIncrement,
			Desc:       plocale.DDLCheckAutoIncrementDesc,
			Annotation: plocale.DDLCheckAutoIncrementAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
		},
		Message: plocale.DDLCheckAutoIncrementMessage,
		Func:    checkAutoIncrement,
	},
	{
		Rule: SourceRule{ // rename table t1 to t2;
			Name:       DDLNotAllowRenaming,
			Desc:       plocale.DDLNotAllowRenamingDesc,
			Annotation: plocale.DDLNotAllowRenamingAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DDLNotAllowRenamingMessage,
		Func:         ddlNotAllowRenaming,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainFullIndexScan,
			Desc:       plocale.DMLCheckExplainFullIndexScanDesc,
			Annotation: plocale.DMLCheckExplainFullIndexScanAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckExplainFullIndexScanMessage,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckLimitOffsetNum,
			Desc:       plocale.DMLCheckLimitOffsetNumDesc,
			Annotation: plocale.DMLCheckLimitOffsetNumAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.DMLCheckLimitOffsetNumParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message:      plocale.DMLCheckLimitOffsetNumMessage,
		AllowOffline: true,
		Func:         checkLimitOffsetNum,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckUpdateOrDeleteHasWhere,
			Desc:       plocale.DMLCheckUpdateOrDeleteHasWhereDesc,
			Annotation: plocale.DMLCheckUpdateOrDeleteHasWhereAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		Message:      plocale.DMLCheckUpdateOrDeleteHasWhereMessage,
		AllowOffline: true,
		Func:         checkUpdateOrDeleteHasWhere,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSortColumnLength,
			Desc:       plocale.DMLCheckSortColumnLengthDesc,
			Annotation: plocale.DMLCheckSortColumnLengthAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2000",
					Desc:  plocale.DMLCheckSortColumnLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckSortColumnLengthMessage,
		Func:         checkSortColumnLength,
	},
	{
		Rule: SourceRule{
			Name:       AllCheckPrepareStatementPlaceholders,
			Desc:       plocale.AllCheckPrepareStatementPlaceholdersDesc,
			Annotation: plocale.AllCheckPrepareStatementPlaceholdersAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "100",
					Desc:  plocale.AllCheckPrepareStatementPlaceholdersParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: true,
		Message:      plocale.AllCheckPrepareStatementPlaceholdersMessage,
		Func:         checkPrepareStatementPlaceholders,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainExtraUsingIndexForSkipScan,
			Desc:       plocale.DMLCheckExplainExtraUsingIndexForSkipScanDesc,
			Annotation: plocale.DMLCheckExplainExtraUsingIndexForSkipScanAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckExplainExtraUsingIndexForSkipScanMessage,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckAffectedRows,
			Desc:       plocale.DMLCheckAffectedRowsDesc,
			Annotation: plocale.DMLCheckAffectedRowsAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10000",
					Desc:  plocale.DMLCheckAffectedRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckAffectedRowsMessage,
		Func:         checkAffectedRows,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSameTableJoinedMultipleTimes,
			Desc:       plocale.DMLCheckSameTableJoinedMultipleTimesDesc,
			Annotation: plocale.DMLCheckSameTableJoinedMultipleTimesAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckSameTableJoinedMultipleTimesMessage,
		Func:         checkSameTableJoinedMultipleTimes,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckExplainUsingIndex,
			Desc:       plocale.DMLCheckExplainUsingIndexDesc,
			Annotation: plocale.DMLCheckExplainUsingIndexAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckExplainUsingIndexMessage,
		Func:         checkExplain,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckInsertSelect,
			Desc:       plocale.DMLCheckInsertSelectDesc,
			Annotation: plocale.DMLCheckInsertSelectAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DMLCheckInsertSelectMessage,
		Func:         checkInsertSelect,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckAggregate,
			Desc:       plocale.DMLCheckAggregateDesc,
			Annotation: plocale.DMLCheckAggregateAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DMLCheckAggregateMessage,
		Func:         checkAggregateFunc,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckColumnNotNULL,
			Desc:       plocale.DDLCheckColumnNotNULLDesc,
			Annotation: plocale.DDLCheckColumnNotNULLAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DDLCheckColumnNotNULLMessage,
		Func:         checkColumnNotNull,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckIndexSelectivity,
			Desc:       plocale.DMLCheckIndexSelectivityDesc,
			Annotation: plocale.DMLCheckIndexSelectivityAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "70",
					Desc:  plocale.DMLCheckIndexSelectivityParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckIndexSelectivityMessage,
		Func:         checkIndexSelectivity,
	},
	{
		// 该规则只适用于库表元数据扫描并且需要与停用上线审核模式规则一起使用
		Rule: SourceRule{
			Name:       DDLCheckTableRows,
			Desc:       plocale.DDLCheckTableRowsDesc,
			Annotation: plocale.DDLCheckTableRowsAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeUsageSuggestion,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "1000",
					Desc:  plocale.DDLCheckTableRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		Message: plocale.DDLCheckTableRowsMessage,
		Func:    checkTableRows,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCompositeIndexDistinction,
			Desc:       plocale.DDLCheckCompositeIndexDistinctionDesc,
			Annotation: plocale.DDLCheckCompositeIndexDistinctionAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: false,
		Message:      plocale.DDLCheckCompositeIndexDistinctionMessage,
		Func:         checkCompositeIndexSelectivity,
	},
	{
		Rule: SourceRule{
			Name:       DDLAvoidText,
			Desc:       plocale.DDLAvoidTextDesc,
			Annotation: plocale.DDLAvoidTextAnnotation,
			Level:      driverV2.RuleLevelNotice,
			Category:   plocale.RuleTypeDDLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DDLAvoidTextMessage,
		Func:         checkText,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckSelectRows,
			Desc:       plocale.DMLCheckSelectRowsDesc,
			Annotation: plocale.DMLCheckSelectRowsAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10",
					Desc:  plocale.DMLCheckSelectRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckSelectRowsMessage,
		Func:         checkSelectRows,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckScanRows,
			Desc:       plocale.DMLCheckScanRowsDesc,
			Annotation: plocale.DMLCheckScanRowsAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "10",
					Desc:  plocale.DMLCheckScanRowsParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckScanRowsMessage,
		Func:         checkScanRows,
	},
	{
		Rule: SourceRule{
			Name:       DMLMustUseLeftMostPrefix,
			Desc:       plocale.DMLMustUseLeftMostPrefixDesc,
			Annotation: plocale.DMLMustUseLeftMostPrefixAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexInvalidation,
		},
		AllowOffline: false,
		Message:      plocale.DMLMustUseLeftMostPrefixMessage,
		Func:         mustMatchLeftMostPrefix,
	},
	{
		Rule: SourceRule{
			Name:       DMLMustMatchLeftMostPrefix,
			Desc:       plocale.DMLMustMatchLeftMostPrefixDesc,
			Annotation: plocale.DMLMustMatchLeftMostPrefixAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexInvalidation,
		},
		AllowOffline: false,
		Message:      plocale.DMLMustMatchLeftMostPrefixMessage,
		Func:         mustMatchLeftMostPrefix,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckJoinFieldUseIndex,
			Desc:       plocale.DMLCheckJoinFieldUseIndexDesc,
			Annotation: plocale.DMLCheckJoinFieldUseIndexAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexInvalidation,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckJoinFieldUseIndexMessage,
		Func:         checkJoinFieldUseIndex,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckJoinFieldCharacterSetAndCollation,
			Desc:       plocale.DMLCheckJoinFieldCharacterSetAndCollationDesc,
			Annotation: plocale.DMLCheckJoinFieldCharacterSetAndCollationAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexInvalidation,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckJoinFieldCharacterSetAndCollationMessage,
		Func:         checkJoinFieldCharacterSetAndCollation,
	},
	{
		Rule: SourceRule{
			Name:       DMLCheckMathComputationOrFuncOnIndex,
			Desc:       plocale.DMLCheckMathComputationOrFuncOnIndexDesc,
			Annotation: plocale.DMLCheckMathComputationOrFuncOnIndexAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeIndexInvalidation,
		},
		AllowOffline: false,
		Message:      plocale.DMLCheckMathComputationOrFuncOnIndexMessage,
		Func:         checkMathComputationOrFuncOnIndex,
	},
	{
		Rule: SourceRule{
			Name:       DMLSQLExplainLowestLevel,
			Desc:       plocale.DMLSQLExplainLowestLevelDesc,
			Annotation: plocale.DMLSQLExplainLowestLevelAnnotation,
			Level:      driverV2.RuleLevelWarn,
			Category:   plocale.RuleTypeDDLConvention,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "range,ref,const,eq_ref,system,NULL",
					Desc:  plocale.DMLSQLExplainLowestLevelParams1,
					Type:  params.ParamTypeString,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DMLSQLExplainLowestLevelMessage,
		Func:         checkSQLExplainLowestLevel,
	},
	{
		Rule: SourceRule{
			Name:       DDLAvoidFullText,
			Desc:       plocale.DDLAvoidFullTextDesc,
			Annotation: plocale.DDLAvoidFullTextAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		AllowOffline: true,
		Message:      plocale.DDLAvoidFullTextMessage,
		Func:         avoidFullText,
	},
	{
		Rule: SourceRule{
			Name:       DDLAvoidGeometry,
			Desc:       plocale.DDLAvoidGeometryDesc,
			Annotation: plocale.DDLAvoidGeometryAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		AllowOffline: true,
		Message:      plocale.DDLAvoidGeometryMessage,
		Func:         avoidGeometry,
	},
	{
		Rule: SourceRule{
			Name:       DMLAvoidWhereEqualNull,
			Desc:       plocale.DMLAvoidWhereEqualNullDesc,
			Annotation: plocale.DMLAvoidWhereEqualNullAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeDMLConvention,
		},
		AllowOffline: true,
		Message:      plocale.DMLAvoidWhereEqualNullMessage,
		Func:         avoidWhereEqualNull,
	},
	{
		Rule: SourceRule{
			Name:       DDLAvoidEvent,
			Desc:       plocale.DDLAvoidEventDesc,
			Annotation: plocale.DDLAvoidEventAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
		},
		AllowOffline: true,
		Message:      plocale.DDLAvoidEventMessage,
		Func:         avoidEvent,
	},
	{
		Rule: SourceRule{
			Name:       DDLCheckCharLength,
			Desc:       plocale.DDLCheckCharLengthDesc,
			Annotation: plocale.DDLCheckCharLengthAnnotation,
			Level:      driverV2.RuleLevelError,
			Category:   plocale.RuleTypeUsageSuggestion,
			Params: []*SourceParam{
				{
					Key:   DefaultSingleParamKeyName,
					Value: "2000",
					Desc:  plocale.DDLCheckCharLengthParams1,
					Type:  params.ParamTypeInt,
				},
			},
		},
		AllowOffline: false,
		Message:      plocale.DDLCheckCharLengthMessage,
		Func:         checkCharLength,
	},
}
